#include "mongoc_const.h"
#include "mongoc_data.h"

int write_data_zlev(int cid, int nlon, int nlat,
                    double t2[nlat][nlon][12]) {
  if (cid >= nbundle) {
    return FORTRAN_MONGO_NO_ERROR;
  }
  struct MongoObjectBundle *bundle = &bundles[cid];

  bson_error_t error;
  size_t ndoc = 100000;
  bson_t **docs = malloc(ndoc * sizeof(bson_t*));
  size_t g = 0, l = 0, m = 0;
  char key[3];

  for (int j = 0; j < nlat; ++j) {
    for (int i = 0; i < nlon; ++i) {
      if (t2[j][i][0] < 10000) {
        docs[m] = BCON_NEW(
          "grid_id", BCON_INT32(g)
        );
        bson_t child;
        // t2
        bson_init(&child);
        bson_append_array_begin(docs[m], "t2", -1, &child);
        for (int k = 0; k < 12; ++k) { // months
          sprintf(key, "%d", k);
          BSON_APPEND_DOUBLE(&child, key, t2[j][i][k] - 273.15);
        }
        bson_append_array_end(docs[m], &child);
        bson_destroy(&child);
        m++;
        if (m == ndoc) {
          printf("==> Insert %ld-%ld documents ...\n", l - ndoc + 1, l);
          if (!mongoc_collection_insert_many(bundle->col, docs, ndoc, NULL, NULL, &error)) {
            fprintf(stderr, "[Error]: Failed to insert data: %s\n", error.message);
            return EXIT_FAILURE;
          }
          for (m = 0; m < ndoc; ++m) {
            bson_destroy(docs[m]);
          }
          m = 0;
        }
        l++;
      }
      g++;
    }
  }
  ndoc = m;
  if (ndoc > 0) {
    printf("==> Insert %ld-%ld documents ...\n", l - m, l - 1);
    if (!mongoc_collection_insert_many(bundle->col, docs, ndoc, NULL, NULL, &error)) {
      fprintf(stderr, "[Error]: Failed to insert data: %s\n", error.message);
      return EXIT_FAILURE;
    }
  }
  for (m = 0; m < ndoc; ++m) {
    bson_destroy(docs[m]);
  }
  free(docs);

  return FORTRAN_MONGO_NO_ERROR;

}
